1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package com.sun.media.sound;
26
27
28
29
30
31
32 public class SoftEnvelopeGenerator implements SoftProcess {
33
34 public final static int EG_OFF = 0;
35 public final static int EG_DELAY = 1;
36 public final static int EG_ATTACK = 2;
37 public final static int EG_HOLD = 3;
38 public final static int EG_DECAY = 4;
39 public final static int EG_SUSTAIN = 5;
40 public final static int EG_RELEASE = 6;
41 public final static int EG_SHUTDOWN = 7;
42 public final static int EG_END = 8;
43 int max_count = 10;
44 int used_count = 0;
45 private int[] stage = new int[max_count];
46 private int[] stage_ix = new int[max_count];
47 private double[] stage_v = new double[max_count];
48 private int[] stage_count = new int[max_count];
49 private double[][] on = new double[max_count][1];
50 private double[][] active = new double[max_count][1];
51 private double[][] out = new double[max_count][1];
52 private double[][] delay = new double[max_count][1];
53 private double[][] attack = new double[max_count][1];
54 private double[][] hold = new double[max_count][1];
55 private double[][] decay = new double[max_count][1];
56 private double[][] sustain = new double[max_count][1];
57 private double[][] release = new double[max_count][1];
58 private double[][] shutdown = new double[max_count][1];
59 private double[][] release2 = new double[max_count][1];
60 private double[][] attack2 = new double[max_count][1];
61 private double[][] decay2 = new double[max_count][1];
62 private double control_time = 0;
63
64 public void reset() {
65 for (int i = 0; i < used_count; i++) {
66 stage[i] = 0;
67 on[i][0] = 0;
68 out[i][0] = 0;
69 delay[i][0] = 0;
70 attack[i][0] = 0;
71 hold[i][0] = 0;
72 decay[i][0] = 0;
73 sustain[i][0] = 0;
74 release[i][0] = 0;
75 shutdown[i][0] = 0;
76 attack2[i][0] = 0;
77 decay2[i][0] = 0;
78 release2[i][0] = 0;
79 }
80 used_count = 0;
81 }
82
83 public void init(SoftSynthesizer synth) {
84 control_time = 1.0 / synth.getControlRate();
85 processControlLogic();
86 }
87
88 public double[] get(int instance, String name) {
89 if (instance >= used_count)
90 used_count = instance + 1;
91 if (name == null)
92 return out[instance];
93 if (name.equals("on"))
94 return on[instance];
95 if (name.equals("active"))
96 return active[instance];
97 if (name.equals("delay"))
98 return delay[instance];
99 if (name.equals("attack"))
100 return attack[instance];
101 if (name.equals("hold"))
102 return hold[instance];
103 if (name.equals("decay"))
104 return decay[instance];
105 if (name.equals("sustain"))
106 return sustain[instance];
107 if (name.equals("release"))
108 return release[instance];
109 if (name.equals("shutdown"))
110 return shutdown[instance];
111 if (name.equals("attack2"))
112 return attack2[instance];
113 if (name.equals("decay2"))
114 return decay2[instance];
115 if (name.equals("release2"))
116 return release2[instance];
117
118 return null;
119 }
120
121 public void processControlLogic() {
122 for (int i = 0; i < used_count; i++) {
123
124 if (stage[i] == EG_END)
125 continue;
126
127 if ((stage[i] > EG_OFF) && (stage[i] < EG_RELEASE)) {
128 if (on[i][0] < 0.5) {
129 if (on[i][0] < -0.5) {
130 stage_count[i] = (int)(Math.pow(2,
131 this.shutdown[i][0] / 1200.0) / control_time);
132 if (stage_count[i] < 0)
133 stage_count[i] = 0;
134 stage_v[i] = out[i][0];
135 stage_ix[i] = 0;
136 stage[i] = EG_SHUTDOWN;
137 } else {
138 if ((release2[i][0] < 0.000001) && release[i][0] < 0
139 && Double.isInfinite(release[i][0])) {
140 out[i][0] = 0;
141 active[i][0] = 0;
142 stage[i] = EG_END;
143 continue;
144 }
145
146 stage_count[i] = (int)(Math.pow(2,
147 this.release[i][0] / 1200.0) / control_time);
148 stage_count[i]
149 += (int)(this.release2[i][0]/(control_time * 1000));
150 if (stage_count[i] < 0)
151 stage_count[i] = 0;
152
153 stage_ix[i] = 0;
154
155 double m = 1 - out[i][0];
156 stage_ix[i] = (int)(stage_count[i] * m);
157
158 stage[i] = EG_RELEASE;
159 }
160 }
161 }
162
163 switch (stage[i]) {
164 case EG_OFF:
165 active[i][0] = 1;
166 if (on[i][0] < 0.5)
167 break;
168 stage[i] = EG_DELAY;
169 stage_ix[i] = (int)(Math.pow(2,
170 this.delay[i][0] / 1200.0) / control_time);
171 if (stage_ix[i] < 0)
172 stage_ix[i] = 0;
173 case EG_DELAY:
174 if (stage_ix[i] == 0) {
175 double attack = this.attack[i][0];
176 double attack2 = this.attack2[i][0];
177
178 if (attack2 < 0.000001
179 && (attack < 0 && Double.isInfinite(attack))) {
180 out[i][0] = 1;
181 stage[i] = EG_HOLD;
182 stage_count[i] = (int)(Math.pow(2,
183 this.hold[i][0] / 1200.0) / control_time);
184 stage_ix[i] = 0;
185 } else {
186 stage[i] = EG_ATTACK;
187 stage_count[i] = (int)(Math.pow(2,
188 attack / 1200.0) / control_time);
189 stage_count[i] += (int)(attack2 / (control_time * 1000));
190 if (stage_count[i] < 0)
191 stage_count[i] = 0;
192 stage_ix[i] = 0;
193 }
194 } else
195 stage_ix[i]--;
196 break;
197 case EG_ATTACK:
198 stage_ix[i]++;
199 if (stage_ix[i] >= stage_count[i]) {
200 out[i][0] = 1;
201 stage[i] = EG_HOLD;
202 } else {
203
204 double a = ((double)stage_ix[i]) / ((double)stage_count[i]);
205 a = 1 + ((40.0 / 96.0) / Math.log(10)) * Math.log(a);
206 if (a < 0)
207 a = 0;
208 else if (a > 1)
209 a = 1;
210 out[i][0] = a;
211 }
212 break;
213 case EG_HOLD:
214 stage_ix[i]++;
215 if (stage_ix[i] >= stage_count[i]) {
216 stage[i] = EG_DECAY;
217 stage_count[i] = (int)(Math.pow(2,
218 this.decay[i][0] / 1200.0) / control_time);
219 stage_count[i] += (int)(this.decay2[i][0]/(control_time*1000));
220 if (stage_count[i] < 0)
221 stage_count[i] = 0;
222 stage_ix[i] = 0;
223 }
224 break;
225 case EG_DECAY:
226 stage_ix[i]++;
227 double sustain = this.sustain[i][0] * (1.0 / 1000.0);
228 if (stage_ix[i] >= stage_count[i]) {
229 out[i][0] = sustain;
230 stage[i] = EG_SUSTAIN;
231 if (sustain < 0.001) {
232 out[i][0] = 0;
233 active[i][0] = 0;
234 stage[i] = EG_END;
235 }
236 } else {
237 double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
238 out[i][0] = (1 - m) + sustain * m;
239 }
240 break;
241 case EG_SUSTAIN:
242 break;
243 case EG_RELEASE:
244 stage_ix[i]++;
245 if (stage_ix[i] >= stage_count[i]) {
246 out[i][0] = 0;
247 active[i][0] = 0;
248 stage[i] = EG_END;
249 } else {
250 double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
251 out[i][0] = (1 - m);
252
253 if (on[i][0] < -0.5) {
254 stage_count[i] = (int)(Math.pow(2,
255 this.shutdown[i][0] / 1200.0) / control_time);
256 if (stage_count[i] < 0)
257 stage_count[i] = 0;
258 stage_v[i] = out[i][0];
259 stage_ix[i] = 0;
260 stage[i] = EG_SHUTDOWN;
261 }
262
263
264 if (on[i][0] > 0.5) {
265 sustain = this.sustain[i][0] * (1.0 / 1000.0);
266 if (out[i][0] > sustain) {
267 stage[i] = EG_DECAY;
268 stage_count[i] = (int)(Math.pow(2,
269 this.decay[i][0] / 1200.0) / control_time);
270 stage_count[i] +=
271 (int)(this.decay2[i][0]/(control_time*1000));
272 if (stage_count[i] < 0)
273 stage_count[i] = 0;
274 m = (out[i][0] - 1) / (sustain - 1);
275 stage_ix[i] = (int) (stage_count[i] * m);
276 }
277 }
278
279 }
280 break;
281 case EG_SHUTDOWN:
282 stage_ix[i]++;
283 if (stage_ix[i] >= stage_count[i]) {
284 out[i][0] = 0;
285 active[i][0] = 0;
286 stage[i] = EG_END;
287 } else {
288 double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
289 out[i][0] = (1 - m) * stage_v[i];
290 }
291 break;
292 default:
293 break;
294 }
295 }
296
297 }
298 }